C/C++

推荐列表 站点导航

当前位置:首页 > 脚本编程 > C/C++ >

uva1559-Nim(记忆化+博弈)

来源:网络整理  作者:网友投稿  发布时间:2020-12-27 15:30
题目链接:uva1559-Nim题目大意:有n个人,奇数的为一队,偶数的为一对,两队分别从一堆石子个数为S的石子堆中取石...

题目链接:uva 1559 - Nim

题目大意:有n个人,奇数的为一队,偶数的为一对,两队分别从一堆石子个数为S的石子堆中取石子,取到最后一个石子一方则视为失败。给出各个队员每次可取石子的上限值,然后按照顺序操作。

解题思路:dp[i][s]表示第i个选手操作时剩s个石子时为必胜还是必败。因为是取到最后一个石子的为输,所以最后递归结束的条件和不同的略有不同。
还尝试过可以将石子数减1,然后普通处理也是可以。

/******************* * 取到最后一个石子的输 * ****************/ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 30; const int maxs = 1<<14; int N, S, m[maxn]; int dp[maxn][maxs]; void init () { memset(dp, -1, sizeof(dp)); scanf("%d", &S); for (int i = 0; i < 2 * N; i++) scanf("%d", &m[i]); } bool dfs (int d, int s) { if (s <= 0) return 1; if (d >= 2 * N) d -= 2 * N; if (dp[d][s] != -1) return dp[d][s]; dp[d][s] = 0; for (int i = 1; i <= m[d]; i++) { if (dfs(d + 1, s - i)) continue; dp[d][s] = 1; } return dp[d][s]; } int main () { while (scanf("%d", &N) == 1 && N) { init(); printf("%d\n", dfs(0, S) ? 1 : 0); } return 0; }

相关热词:

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!

本文地址: https://v30.fanwenzhu.com/jiaob/cjj/9729.shtml

相关文章
最新文章
只需要在调用Ctrl+B编译后 只需要在调用Ctrl+B编译后

时间:2021-01-13

OpenGL超级宝典visual studio OpenGL超级宝典visual studio

时间:2021-01-04

Directx11 教程(2) 基本的wi Directx11 教程(2) 基本的wi

时间:2021-01-04

LeetCode11ContainerWithMostWate LeetCode11ContainerWithMostWate

时间:2021-01-04

C语言简单IT之家速成 C语言简单IT之家速成

时间:2020-12-27

三分钟了解Activity工作流 三分钟了解Activity工作流

时间:2020-12-27

编译器是如何实现32位整型 编译器是如何实现32位整型

时间:2020-12-27

C++中lower_bound函数和upper C++中lower_bound函数和upper

时间:2020-12-27

Copyright © www.juheyunku.com      关于 | 合作 | 声明 | 联系 | 更新 | 地图 | Tags

uva1559-Nim(记忆化+博弈)

2020-12-27 编辑:网友投稿

题目链接:uva 1559 - Nim

题目大意:有n个人,奇数的为一队,偶数的为一对,两队分别从一堆石子个数为S的石子堆中取石子,取到最后一个石子一方则视为失败。给出各个队员每次可取石子的上限值,然后按照顺序操作。

解题思路:dp[i][s]表示第i个选手操作时剩s个石子时为必胜还是必败。因为是取到最后一个石子的为输,所以最后递归结束的条件和不同的略有不同。
还尝试过可以将石子数减1,然后普通处理也是可以。

/******************* * 取到最后一个石子的输 * ****************/ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 30; const int maxs = 1<<14; int N, S, m[maxn]; int dp[maxn][maxs]; void init () { memset(dp, -1, sizeof(dp)); scanf("%d", &S); for (int i = 0; i < 2 * N; i++) scanf("%d", &m[i]); } bool dfs (int d, int s) { if (s <= 0) return 1; if (d >= 2 * N) d -= 2 * N; if (dp[d][s] != -1) return dp[d][s]; dp[d][s] = 0; for (int i = 1; i <= m[d]; i++) { if (dfs(d + 1, s - i)) continue; dp[d][s] = 1; } return dp[d][s]; } int main () { while (scanf("%d", &N) == 1 && N) { init(); printf("%d\n", dfs(0, S) ? 1 : 0); } return 0; }

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供学习参考!
本文地址为 https://v30.fanwenzhu.com/jiaob/cjj/9729.shtml

相关文章

风云图片

推荐阅读

返回C/C++频道首页